i am implementing two classes that share many methods but i cant make one inherit from the other as it doesn't make sense so i opted for a shared interface with all the shared methods. but i realized that many methods have the same implementation for both classes too so my question would be how can i make these methods "inherit" from a default method kind of like "super" methods in inheritance?
one solution that im thinking of is creating a parent class so that both my classes can inherit from it
Inheritance should be used when you need to refer to a common ancestor, not to 'share' common code. You say that the two objects do not have this relationship but do have common code - the obvious approach is to factor that out into it's own class (or interface or whatever) and compose into your objects:
You didn't provide an example so I'll make one up:
class CommonStuff {
// common members here
}
class One {
private final CommonStuff common;
}
class Two {
private final CommonStuff common;
}
No need for inheritance and its inherent hard coupling (pun intended).
Yes Abstract Class is the right approach for this if you have some default implementation for methods otherwise you can go for interface.
Write all your common piece of logic in your Abstract class methods and make these methods abstract if you want the subclass to override the implementation otherwise you don't need to make them abstract methods
To expand on my comment: you want to use composition as well as the decorator pattern with delegation
For example:
public interface Foo {
public void a();
public void b();
}
// used as the inner class
public class ConcreteFoo implements Foo {
public void a() {
// implementation for a
}
public void b() {
// implementation for b
}
}
public class MyContainerA implements Foo {
private Foo innerFoo;
public MyContainerA(Foo innerFoo) {
this.innerFoo = innerFoo;
}
public void a() {
// delegate the method call to the contained object
innerFoo.a();
}
public void b() {
// delegate
innerFoo.b();
}
public void methodOnlyInContainerA() {
}
}
public class MyContainerB implements Foo {
private Foo innerFoo;
public MyContainerB(Foo innerFoo) {
this.innerFoo = innerFoo;
}
public void a() {
innerFoo.a();
}
public void b() {
innerFoo.b();
}
public void methodOnlyInContainerB() {
}
}
elsewhere:
Foo foo = new ConcreteFoo();
// both guys below use the same inner class
MyContainerA contA = new MyContainerA(foo);
MyContainerB contB = new MyContainerB(foo);